home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Tools 4
/
Amiga Tools 4.iso
/
tools
/
protect-your-privacy
/
p.g.p.
/
pgpsendmail
/
source
/
expandalias.c
next >
Wrap
C/C++ Source or Header
|
1996-02-26
|
12KB
|
362 lines
/*
* $Filename: expandalias $
* $Revision: 1.11 $
* $Date: 1994/03/13 18:24:34 $
*
* Copyright (C) 1993 by Peter Simons <simons@peti.GUN.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id: expandalias.c,v 1.11 1994/03/13 18:24:34 simons Exp simons $
*
*/
/**************************************************************************
* *
* Sektion: Macros, Definitions, Includes, Structures *
* *
**************************************************************************/
/************************************* Includes ***********/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <time.h>
#include <libraries/netsupport.h>
#include <proto/netsupport.h>
#include "protos.h"
/************************************* Defines ************/
#define MAX_RECEIPIENTS 1024 /*
* max. number of receipients
*/
#define HASHSIZE 256
#define HASHMASK (HASHSIZE-1)
#define HF_TERM 0x01 /* terminator name */
#define HF_ALIAS 0x02 /* alias */
#define HF_LOADED 0x04 /* def loaded */
#define HF_NOEXPAND 0x08 /* do not expand alias */
typedef struct Hash {
struct Hash *Next;
short NumAlias; /* # of aliases */
short Flags;
char *Name; /* aliased user name */
union {
struct Hash **Alias; /* list of aliases */
long Offset; /* offset into file */
} u;
} Hash;
/************************************* Prototypes *********/
static void callBack(char *, long, int);
static Hash *FindHashObject(const char *);
static void LoadHashObject(Hash *);
static int HashFunc(const char *);
/************************************* global Variables ***/
static const char __RCSId[] = "$Id: expandalias.c,v 1.11 1994/03/13 18:24:34 simons Exp simons $";
static char **new_receipients;
static Hash *HashTab[HASHSIZE];
static char Tmp[256];
/**************************************************************************
* *
* Sektion: Unterprogramme *
* *
**************************************************************************/
char **ExpandAliases(char *receipients[])
{
char **new_receipients2;
if (*receipients == NULL)
return NULL;
if ((new_receipients = malloc(sizeof(char *[MAX_RECEIPIENTS]))) == NULL)
return NULL;
new_receipients2 = new_receipients;
LoadAliases();
while (*receipients != NULL) {
UserAliasList(*receipients, (int (*)(char *, long, int)) callBack, 0L, 1);
receipients++;
}
*new_receipients = NULL;
return new_receipients2;
}
static void callBack(char *name, long dummy, int show)
{
switch (name[0]) {
case '|':
case '>':
case '<':
break;
case '\\':
++name;
default:
*new_receipients = name;
new_receipients++;
break;
}
}
void LoadAliases(void)
{
FILE *fi = fopen("UULib:Aliases", "r");
short i, j, k, line = 0;
long offset, newoffset = 0;
Hash *h;
char *buf = Tmp;
if (fi == NULL) {
MakeLogEntry(PRGNAME, MLE_FATAL_ERROR, "Can't open UULib:Aliases!");
return;
}
while (fgets(buf, 256, fi)) {
offset = newoffset;
newoffset = ftell(fi);
++line;
for (i = 0; buf[i] == ' ' || buf[i] == 9; ++i) ;
if (buf[i] == '#' || buf[i] == '\n')
continue;
for (j = i; buf[j] && buf[j] != ':'; ++j) ;
if (buf[j] == 0) {
MakeLogEntry(PRGNAME, MLE_FATAL_ERROR, "No Colon UULib:Aliases line %d.", line);
continue;
}
buf[j] = 0;
k = HashFunc(buf + i);
h = malloc(sizeof(Hash));
h->Next = HashTab[k];
h->NumAlias = 0;
h->Flags = HF_ALIAS;
h->Name = malloc(strlen(buf + i) + 1);
if (buf[j + 1] == ':') {
h->Flags |= HF_NOEXPAND;
++j;
}
h->u.Offset = offset + j + 1;
strcpy(h->Name, buf + i);
HashTab[k] = h;
/*
* if trailing comma, list continues onto next line
*/
for (;;) {
for (++j; buf[j]; ++j) ;
while (buf[j - 1] == ' ' || buf[j - 1] == 9 || buf[j - 1] == '\n')
--j;
if (buf[j - 1] != ',')
break;
if (fgets(buf, 256, fi) == NULL)
break;
newoffset = ftell(fi);
j = 0;
}
}
fclose(fi);
}
static Hash *FindHashObject(const char *name)
{
short k = HashFunc(name);
Hash *h;
for (h = HashTab[k]; h; h = h->Next) {
if (stricmp(name, h->Name) == 0)
return (h);
}
return (NULL);
}
static void LoadHashObject(Hash * hash)
{
FILE *fi = fopen("UUlib:Aliases", "r");
char *buf = Tmp;
short i, j;
short c;
short numalloc = 4;
Hash **hv = malloc(sizeof(Hash *) * 4);
Hash *h;
if (fi == NULL) {
MakeLogEntry(PRGNAME, MLE_FATAL_ERROR, "Can't open UULib:Aliases!");
return;
}
hash->Flags |= HF_LOADED;
fseek(fi, hash->u.Offset, 0);
while (fgets(buf, 256, fi)) {
i = 0;
c = 'x';
for (i = 0; buf[i] == ' ' || buf[i] == 9; ++i) ;
if (buf[i] == '#')
continue;
for (;;) {
while (buf[i] == ' ' || buf[i] == 9)
++i;
if (buf[i] == 0 || buf[i] == '\n' || buf[i] == '#')
break;
for (j = i; buf[j] != '\n' && buf[j] != ' ' && buf[j] != 9 && buf[j] != ','; ++j) {
if (buf[j] == '\"') {
i = j + 1;
for (++j; buf[j] != '\n' && buf[j] != '\"'; ++j) ;
break;
}
}
c = buf[j];
buf[j] = 0;
/*
* skip remaining junk before comma
*/
while (c && c != '\n' && c != ',')
c = buf[++j];
if ((h = FindHashObject(buf + i)) == NULL) {
short k = HashFunc(buf + i);
h = malloc(sizeof(Hash));
h->Next = HashTab[k];
h->NumAlias = 0;
h->Flags = HF_TERM;
h->Name = malloc(strlen(buf + i) + 1);
h->u.Alias = NULL;
strcpy(h->Name, buf + i);
HashTab[k] = h;
}
if (hash->NumAlias == numalloc) {
Hash **hvo = hv;
short add = 4;
hv = malloc(sizeof(Hash *) * (numalloc + add));
movmem((char *) hvo, (char *) hv, sizeof(Hash *) * numalloc);
numalloc += add;
}
hv[hash->NumAlias++] = h;
if (c == '\n' || c == 0)
i = j;
else
i = j + 1;
}
if (c != ',')
break;
}
hash->u.Alias = hv;
}
int AliasExists(const char *user)
{
if (FindHashObject(user))
return (1);
return (0);
}
/*
* UserAliasList returns whether the 'user' should be displayed in the
* To: field of the letter. Normally it isn't, but if an alias is
* specified to NOT expand on the To: field then the alias name itself
* IS put on the To: field.
*
* showto is passed from an upper level. If set, the callback specifies
* expansion (unless overriden by the alias), else the callback specifies
* no expansion.
*
* In the case where a high level alias is expanded but a low level alias
* is not, the callback function is called for the low level alias with
* a showto of -1, indicating that it should be placed on the To: list
* WITHOUT being placed on the actual send-to list (because its expansion
* is passed normally)
*/
int UserAliasList(const char *user,
int (*callback) (const char *, long, int),
long arg,
int showto)
{
short i;
Hash *hash = FindHashObject(user);
static short stack;
if (++stack == 32) {
MakeLogEntry(PRGNAME, MLE_FATAL_ERROR, "UULib:Aliases recursion near user %s.", user);
--stack;
return 0;
}
if (hash) {
if ((hash->Flags & HF_TERM) == 0) {
if ((hash->Flags & HF_LOADED) == 0)
LoadHashObject(hash);
for (i = 0; i < hash->NumAlias; ++i) {
Hash *h = hash->u.Alias[i];
int r;
if (showto)
r = UserAliasList(h->Name, callback, arg, !(hash->Flags & HF_NOEXPAND));
else
r = UserAliasList(h->Name, callback, arg, 0);
--stack;
if (r && showto && !(hash->Flags & HF_NOEXPAND))
(*callback) (h->Name, arg, -1);
}
}
else {
if (showto)
(*callback) (user, arg, !(hash->Flags & HF_NOEXPAND));
else
(*callback) (user, arg, 0);
}
}
else {
(*callback) (user, arg, showto);
}
--stack;
if (hash && (hash->Flags & HF_NOEXPAND))
return (1);
return (0);
}
static int HashFunc(const char *str)
{
unsigned long v = 0x14FBA5C3;
while (*str) {
v = (v << 5) ^ (*str & 0x1F) ^ (v >> 27);
++str;
}
return ((int) (v & HASHMASK));
}